package com.hzhc.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzhc.common.FileExcelUtil;
import com.hzhc.dto.UserDto;
import com.hzhc.entity.*;
import com.hzhc.enumBean.DdEnum;
import com.hzhc.enumBean.FyEnum;
import com.hzhc.enumBean.ResultUtilCodeEnum;
import com.hzhc.enumBean.YwOrderTypeEnum;
import com.hzhc.mapper.*;
import com.hzhc.service.CntrInfoService;
import com.hzhc.service.CntrLogService;
import com.hzhc.utils.*;
import com.hzhc.vo.*;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 集装箱信息 服务实现类
 * </p>
 *
 * @author 功不唐捐
 * @since 2024-05-23
 */
@Service
@RequiredArgsConstructor
public class CntrInfoServiceImpl extends ServiceImpl<CntrInfoMapper, CntrInfo> implements CntrInfoService {

    private final TrainPlanMapper trainPlanMapper;
    private final TrainPlanDetailMapper detailMapper;
    private final YwOrderCntrMapper ywOrderCntrMapper;
    private final SysUserMapper sysUserMapper;
    private final UserMemberMapper userMemberMapper;
    private final YwOrderMapper ywOrderMapper;
    private final DeclareCarMapper declareCarMapper;
    private final VehicleReservationMapper vehicleReservationMapper;
    private final CntrLogMapper cntrLogMapper;
    private final CntrLogService cntrLogService;
    private final CompanyInfoMapper companyInfoMapper;
    private final CntrInfoMapper infoMapper;
    private final VehicleReservationMapper reservationMapper;
    private final CntrSizeMapper cntrSizeMapper;

    @Override
    public List<CntrInfoVo> getAllList(Page<CntrInfoVo> page, CntrInfoVo vo) {
        IPage<CntrInfoVo> iPage = baseMapper.getAllList(page,vo);
        return iPage.getRecords();
    }

    @Override
    public List<CntrInfoVo> getAllYzsList(Page<CntrInfoVo> page, CntrInfoVo vo) {
        IPage<CntrInfoVo> iPage = baseMapper.getAllYzsList(page,vo);
        return iPage.getRecords();
    }

    @Override
    public ResultUtil<T> addCntrInfo(CntrInfo info) {
        info.setCreatetime(LocalDateTime.now());
        if(StringUtils.isEmpty(info.getEfFlag())){
            info.setEfFlag("F");
        }
        if(StringUtils.isEmpty(info.getTradeType())){
            info.setTradeType("N");
        }

        // 校验箱号开头，并设置状态码
        String cntrNo = info.getCntrNo();

        boolean b = CheckUtils.checkCntrNo(cntrNo);
        if (!b){
            return ResultUtil.build(400,"箱号错误(4位大写字母+7位数字)");
        }


        //添加修箱状态
        if(info.getCntrXx()!=null){
            int cntrXx = info.getCntrXx(); // 从前端获取的修箱状态
            info.setCntrXx(cntrXx);
        }

        if (info.getStatus()==0){//入场  校验贝位
            ResultUtil<T> resultUtil = checkBay(info);
            if (resultUtil.getCode()!=200){
                return resultUtil;
            }
        }
        if(StringUtils.isNotEmpty(info.getBay()) && "待整改区".equals(info.getBay())){
            info.setRemark(FyEnum.DZG.getName());
            info.setCntrWorkRemark(FyEnum.DZG.getName());
            info.setLockFlag(1);
            info.setLockStart(LocalDateTime.now());
            info.setLockRemark(FyEnum.DZG.getName());
            info.setOperateType("DZG");
        }
//        info.setCntrWorkRemark(FyEnum.DFY.getName());


        save(info);
        return ResultUtil.ok();
    }

    @Override
    public Boolean checkCntrNo(CntrInfo info) {
        LambdaQueryWrapper<CntrInfo> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(CntrInfo::getDisable,false)
                .eq(CntrInfo::getCntrNo,info.getCntrNo());

        int num = count(wrapper);

        return num<=0;
    }

    @Override
    public ResultUtil<T> checkBay(CntrInfo info) {
        if (StrUtil.isBlank(info.getBay())) {
            return ResultUtil.build(400, "贝位不能为空,请检查!");
        }
        if (StrUtil.isBlank(info.getCntrSize())) {
            return ResultUtil.build(400, "尺寸不能为空,请检查!");
        }
//        if(info.getBay().matches(".*[\u4e00-\u9fa5]+.*")){
//            return ResultUtil.build(200, "");
//        }
        //贝位相同
        List<CntrInfo> infoList = baseMapper.selectList(Wrappers.<CntrInfo>lambdaQuery()
                .ne(CntrInfo::getCntrNo, info.getCntrNo())
                .eq(CntrInfo::getBay, info.getBay())
                .eq(CntrInfo::getStatus,0)
                .eq(CntrInfo::getDisable, 0)
                .select(CntrInfo::getCntrNo));
        if (infoList != null && !infoList.isEmpty()) {
            return ResultUtil.build(400, "贝位"+info.getBay()+"已被占用,请重新选择!");
        }
        String[] bays = info.getBay().split("-");
        String area = bays[0];
        String bay1 = bays[1];
        String bay2 = bays[2];
        String bay3 = bays[3];
        //贝位小于10加0
        int i = Integer.parseInt(bay1);
        int i1 = Integer.parseInt(bay1) - 1;
        int i2 = Integer.parseInt(bay1) + 1;
        int i3 = 0;
        int i4 = 0;
        if (info.getCntrSize().startsWith("4")) {
             i3 = Integer.parseInt(bay1) - 2; //40尺寸 不止校验相邻的贝位还要校验前一个偶数贝位和后一个偶数贝位
             i4 = Integer.parseInt(bay1) + 2; //40尺寸 不止校验相邻的贝位还要校验前一个偶数贝位和后一个偶数贝位
        }
        String b = i > 9 ? bay1:"0"+ i;
        String b1 = i1 > 9 ? String.valueOf(i1):"0"+ i1;
        String b2 = i2 > 9 ? String.valueOf(i2):"0"+ i2;
        String b3 = i3 > 9 ? String.valueOf(i3):"0"+ i3;
        String b4 = i4 > 9 ? String.valueOf(i4):"0"+ i4;
        //下面一层
        StringBuilder under = new StringBuilder();
        if (!"1".equals(bay3)) {
            under.append(area).append("-").append(b).append("-").append(bay2).append("-").append(Integer.parseInt(bay3) - 1);
        }
        if (under.length() > 0){
            //下面箱
            CntrInfo one = getOne(Wrappers.<CntrInfo>lambdaQuery().eq(CntrInfo::getBay, under.toString()).ne(CntrInfo::getCntrNo,info.getCntrNo())
                    .eq(CntrInfo::getDisable, 0).eq(CntrInfo::getStatus,0).select(CntrInfo::getCntrNo,CntrInfo::getCntrSize,CntrInfo::getBay,CntrInfo::getEfFlag));

            if (one == null) {
                return ResultUtil.build(400, "贝位"+info.getBay()+"下面没有箱子,请检查");
            } else {
                if(StrUtil.isNotBlank(info.getEfFlag())){
                    if (!info.getEfFlag().equals(one.getEfFlag())) {
                        return ResultUtil.build(400, "箱"+info.getCntrNo()+"空重与此列不符,请检查");
                    }
                }
            }
        }

        //40尺寸
        if (info.getCntrSize().startsWith("4")) {
            if (Integer.parseInt(bay1) % 2 != 0){
                return ResultUtil.build(400,"大箱只能放在偶数位,请检查");
            }
            //大箱左右2个奇数贝位和左右2个偶数贝位不能有箱
            List<CntrInfo> bigs = list(Wrappers.<CntrInfo>lambdaQuery()
                    .in(CntrInfo::getBay, area + "-" + b1 + "-" + bay2 + "-" + bay3, area + "-" + b2 + "-" + bay2 + "-" + bay3, area + "-" + b3 + "-" + bay2 + "-" + bay3, area + "-" + b4 + "-" + bay2 + "-" + bay3)
                    .eq(CntrInfo::getDisable, 0).eq(CntrInfo::getStatus,0)
                    .isNotNull(CntrInfo::getBay).ne(CntrInfo::getCntrNo,info.getCntrNo())
                    .select(CntrInfo::getCntrNo,CntrInfo::getCntrSize,CntrInfo::getBay));
            if (bigs != null && !bigs.isEmpty()) {
                return ResultUtil.build(400, "贝位"+info.getBay()+"已被"+bigs.get(0).getCntrNo()+"占用,请检查");
            }
        } else if (info.getCntrSize().startsWith("2")) {
            if (Integer.parseInt(bay1) % 2 == 0){
                return ResultUtil.build(400,"小箱只能放在奇数位,请检查");
            }
            //小箱左右一个贝位不能有箱
            List<CntrInfo> smalls = list(Wrappers.<CntrInfo>lambdaQuery().in(CntrInfo::getBay, area + "-" + b1 + "-" + bay2 + "-" + bay3, area + "-" + b2 + "-" + bay2 + "-" + bay3)
                    .eq(CntrInfo::getDisable, 0).eq(CntrInfo::getStatus,0).isNotNull(CntrInfo::getBay).ne(CntrInfo::getCntrNo,info.getCntrNo())
                    .select(CntrInfo::getCntrNo,CntrInfo::getCntrSize,CntrInfo::getBay));
            if (smalls != null && !smalls.isEmpty()) {
                return ResultUtil.build(400, "贝位"+info.getBay()+"已被占用,请检查");
            }
        }
        return ResultUtil.build(200, "");
    }

    @Override
    public ResultUtil<T> checkOldBay(CntrInfo info) {
        if (StrUtil.isBlank(info.getBay())) {
            return ResultUtil.build(400, "贝位不能为空,请检查!");
        }
        if (StrUtil.isBlank(info.getCntrSize())) {
            return ResultUtil.build(400, "尺寸不能为空,请检查!");
        }
        if(info.getBay().matches(".*[\u4e00-\u9fa5]+.*")){
            return ResultUtil.build(200, "");
        }
        //贝位相同
        List<CntrInfo> infoList = baseMapper.selectList(Wrappers.<CntrInfo>lambdaQuery()
                .ne(CntrInfo::getCntrNo, info.getOldCntrNo())
                .eq(CntrInfo::getBay, info.getBay())
                .eq(CntrInfo::getStatus,0)
                .eq(CntrInfo::getDisable, 0)
                .select(CntrInfo::getCntrNo));
        if (infoList != null && !infoList.isEmpty()) {
            return ResultUtil.build(400, "贝位"+info.getBay()+"已被占用,请重新选择!");
        }
        String[] bays = info.getBay().split("-");
        String area = bays[0];
        String bay1 = bays[1];
        String bay2 = bays[2];
        String bay3 = bays[3];
        //贝位小于10加0
        int i = Integer.parseInt(bay1);
        int i1 = Integer.parseInt(bay1) - 1;
        int i2 = Integer.parseInt(bay1) + 1;
        int i3 = 0;
        int i4 = 0;
        if (info.getCntrSize().startsWith("4")) {
            i3 = Integer.parseInt(bay1) - 2; //40尺寸 不止校验相邻的贝位还要校验前一个偶数贝位和后一个偶数贝位
            i4 = Integer.parseInt(bay1) + 2; //40尺寸 不止校验相邻的贝位还要校验前一个偶数贝位和后一个偶数贝位
        }
        String b = i > 9 ? bay1:"0"+ i;
        String b1 = i1 > 9 ? String.valueOf(i1):"0"+ i1;
        String b2 = i2 > 9 ? String.valueOf(i2):"0"+ i2;
        String b3 = i3 > 9 ? String.valueOf(i3):"0"+ i3;
        String b4 = i4 > 9 ? String.valueOf(i4):"0"+ i4;
        //下面一层
        StringBuilder under = new StringBuilder();
        if (!"1".equals(bay3)) {
            under.append(area).append("-").append(b).append("-").append(bay2).append("-").append(Integer.parseInt(bay3) - 1);
        }
        if (under.length() > 0){
            //下面箱
            CntrInfo one = getOne(Wrappers.<CntrInfo>lambdaQuery().eq(CntrInfo::getBay, under.toString()).ne(CntrInfo::getCntrNo,info.getOldCntrNo())
                    .eq(CntrInfo::getDisable, 0).eq(CntrInfo::getStatus,0).select(CntrInfo::getCntrNo,CntrInfo::getCntrSize,CntrInfo::getBay,CntrInfo::getEfFlag));

            if (one == null) {
                return ResultUtil.build(400, "贝位"+info.getBay()+"下面没有箱子,请检查");
            } else {
                if(StrUtil.isNotBlank(info.getEfFlag())){
                    if (!info.getEfFlag().equals(one.getEfFlag())) {
                        return ResultUtil.build(400, "箱"+info.getCntrNo()+"空重与此列不符,请检查");
                    }
                }
            }
        }

        //40尺寸
        if (info.getCntrSize().startsWith("4")) {
            if (Integer.parseInt(bay1) % 2 != 0){
                return ResultUtil.build(400,"大箱只能放在偶数位,请检查");
            }
            //大箱左右2个奇数贝位和左右2个偶数贝位不能有箱
            List<CntrInfo> bigs = list(Wrappers.<CntrInfo>lambdaQuery()
                    .in(CntrInfo::getBay, area + "-" + b1 + "-" + bay2 + "-" + bay3, area + "-" + b2 + "-" + bay2 + "-" + bay3, area + "-" + b3 + "-" + bay2 + "-" + bay3, area + "-" + b4 + "-" + bay2 + "-" + bay3)
                    .eq(CntrInfo::getDisable, 0).eq(CntrInfo::getStatus,0)
                    .likeRight(CntrInfo::getCntrSize, 4).isNotNull(CntrInfo::getBay).ne(CntrInfo::getCntrNo,info.getOldCntrNo())
                    .select(CntrInfo::getCntrNo,CntrInfo::getCntrSize,CntrInfo::getBay));
            if (bigs != null && !bigs.isEmpty()) {
                return ResultUtil.build(400, "贝位"+info.getBay()+"已被"+bigs.get(0).getCntrNo()+"占用,请检查");
            }
        } else if (info.getCntrSize().startsWith("2")) {
            if (Integer.parseInt(bay1) % 2 == 0){
                return ResultUtil.build(400,"小箱只能放在奇数位,请检查");
            }
            //小箱左右一个贝位不能有箱
            List<CntrInfo> smalls = list(Wrappers.<CntrInfo>lambdaQuery().in(CntrInfo::getBay, area + "-" + b1 + "-" + bay2 + "-" + bay3, area + "-" + b2 + "-" + bay2 + "-" + bay3)
                    .eq(CntrInfo::getDisable, 0).eq(CntrInfo::getStatus,0).isNotNull(CntrInfo::getBay).ne(CntrInfo::getCntrNo,info.getOldCntrNo())
                    .select(CntrInfo::getCntrNo,CntrInfo::getCntrSize,CntrInfo::getBay));
            if (smalls != null && !smalls.isEmpty()) {
                return ResultUtil.build(400, "贝位"+info.getBay()+"已被占用,请检查");
            }
        }
        return ResultUtil.build(200, "");
    }

    //校验左右相邻的贝位是否有箱子
    private Boolean checkBay1(String bay) {
        String[] str=bay.split("-");
        String one=str[0];
        String row=str[2];
        int two = Integer.parseInt(str[1]);
        String before;
        String after;
        String tBefore;
        String tAfter;
        boolean ischeck = true;
        if(two%2==0){
            if(two-1<10){
                before=one+"-"+"0"+(two-1)+"-"+row;
            }else {
                before=one+"-"+(two-1)+"-"+row;
            }
            if(two+1<10){
                after=one+"-"+"0"+(two+1)+"-"+row;
            }else{
                after=one+"-"+(two+1)+"-"+row;
            }

            if(two-2<10){
                tBefore=one+"-"+"0"+(two-2)+"-"+row;
            }else {
                tBefore=one+"-"+(two-2)+"-"+row;
            }
            if(two+2<10){
                tAfter=one+"-"+"0"+(two+2)+"-"+row;
            }else {
                tAfter=one+"-"+(two+2)+"-"+row;
            }
        }else {
            if(two-1<10){
                before=one+"-"+"0"+(two-1)+"-"+row;
            }else {
                before=one+"-"+(two-1)+"-"+row;
            }
            if(two+1<10){
                after=one+"-"+"0"+(two+1)+"-"+row;
            }else{
                after=one+"-"+(two+1)+"-"+row;
            }
            tBefore="";
            tAfter="";
        }
        List<CntrInfo> cntrInfos =  list(new QueryWrapper<CntrInfo>()
                .and(wrapper -> wrapper
                        .likeRight(StrUtil.isNotBlank(before),"bay", before)
                        .or(StrUtil.isNotBlank(after)).likeRight(StrUtil.isNotBlank(after),"bay", after)
                        .or(StrUtil.isNotBlank(tBefore)).likeRight(StrUtil.isNotBlank(tBefore),"bay",tBefore)
                        .or(StrUtil.isNotBlank(tAfter)).likeRight(StrUtil.isNotBlank(tAfter),"bay",tAfter)
                        .eq("status",0)
                        .eq("disable",0)));
        if(cntrInfos != null && !cntrInfos.isEmpty()){
            ischeck = false;
        }
        return  ischeck;
    }

    @Override
    public ResultUtil<T> updateCntrInfo(CntrInfo info) {
        if (info.getStatus() == 0) {
//            if(!(info.getBay().matches(".*[\u4e00-\u9fa5]+.*"))){
                QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<CntrInfo>();
                queryWrapper.eq("bay", info.getBay());
                queryWrapper.eq("status", 0);
                queryWrapper.ne("cntr_no",info.getOldCntrNo());
                queryWrapper.ne("disable", true);
                List<CntrInfo> cfList = baseMapper.selectList(queryWrapper);
                if (!cfList.isEmpty()) {
                    if (!(cfList.get(0).getCntrNo().equals(info.getOldCntrNo()))) {
                        String xhStr = cfList.get(0).getCntrNo();
                        return ResultUtil.build(400, "该贝位已有箱:" + xhStr);
                    }
                }
                // 贝位不重复则修改
                ResultUtil<T> resultUtil = checkBay(info);
                if (resultUtil.getCode()!=200){
                    return resultUtil;
                }
//            }
        } else {
            info.setBay("");
        }


        //修改空重重量
        String lihuo = info.getLhWeight();
        info.setLhWeight(lihuo);

        Integer cntrXx = info.getCntrXx();
        info.setCntrXx(cntrXx);

        //
        CntrInfo cntrInfo = baseMapper.selectById(info.getOldCntrNo());

        if(cntrInfo!=null){
            CntrInfo newInfo=new CntrInfo();
            BeanUtils.copyProperties(info,newInfo);
            newInfo.setOperateType(cntrInfo.getOperateType() + "XG");
            if(StringUtils.isEmpty(newInfo.getEfFlag())){
                newInfo.setEfFlag("F");
            }
            if(StringUtils.isEmpty(newInfo.getTradeType())){
                newInfo.setTradeType("N");
            }

            if(StringUtils.isNotEmpty(cntrInfo.getCntrWorkRemark())){
                newInfo.setCntrWorkRemark(cntrInfo.getCntrWorkRemark());
            }
            if(StringUtils.isNotEmpty(cntrInfo.getCntrWorkRemarkB())){
                newInfo.setCntrWorkRemarkB(cntrInfo.getCntrWorkRemarkB());
            }
            newInfo.setConsigneeLx(info.getReceiveName());
            newInfo.setOrderNo(cntrInfo.getOrderNo());
            newInfo.setUpdatetime(LocalDateTime.now());
            if(StringUtils.isNotEmpty(newInfo.getBay()) && "待整改区".equals(newInfo.getBay())){
                newInfo.setRemark(FyEnum.DZG.getName());
                newInfo.setCntrWorkRemark(FyEnum.DZG.getName());
                newInfo.setLockFlag(1);
                newInfo.setLockStart(LocalDateTime.now());
                newInfo.setLockRemark("待整改");
                newInfo.setOperateType("DZG");
            }
            saveOrUpdate(newInfo);

            if(!(info.getOldCntrNo().equals(info.getCntrNo()))){
                //旧的应该设为不在场 或者删掉
                cntrInfo.setStatus(1);
                cntrInfo.setBay("");
                cntrInfo.setArea("");
                updateById(cntrInfo);
            }
        }

//        info.setRemark(cntrInfo.getRemark() + "修改");


        //修改 箱清单 装卸车清单 箱信息 箱动态 车辆预约

        List<YwOrderCntr> ywOrderCntrs = ywOrderCntrMapper.selectList(new QueryWrapper<YwOrderCntr>().eq("disable", 0)
                .eq("order_no", info.getOrderNo()).eq("cntr_no", info.getOldCntrNo()));
        if(ywOrderCntrs.size()>0){
            for (YwOrderCntr ywOrderCntr : ywOrderCntrs) {
                ywOrderCntr.setCntrNo(info.getCntrNo());
                ywOrderCntr.setCntrSize(info.getCntrSize());
                ywOrderCntr.setGoodsName(info.getGoods());
                ywOrderCntr.setSealNo(info.getSealNo());
                ywOrderCntr.setConsigneePhone(info.getConsigneePhone());
                ywOrderCntr.setWeight(info.getWeightPred().toString());
                ywOrderCntr.setEfFlag(info.getEfFlag());
                ywOrderCntr.setConsignee(info.getConsignee());
                ywOrderCntr.setConsigneeLx(info.getConsigneeLx());
                ywOrderCntrMapper.updateById(ywOrderCntr);
            }
        }

        List<TrainPlanDetail> details = detailMapper.selectList(new QueryWrapper<TrainPlanDetail>().eq("disable", 0)
                .eq("order_no", info.getOrderNo()).eq("cntr_no", info.getOldCntrNo()));
        if(details.size()>0){
            for (TrainPlanDetail detail : details) {
                detail.setCntrNo(info.getCntrNo());
                detail.setCntrSize(info.getCntrSize());
                detail.setGoods(info.getGoods());
                detail.setSealNo(info.getSealNo());
                detail.setConsigneeContact(info.getConsigneePhone());
                detail.setWeightPred(info.getWeightPred());
                detail.setEfFlag(info.getEfFlag());
                detail.setConsignee(info.getConsignee());
                detail.setConsigneeLxr(info.getConsigneeLx());
                detailMapper.updateById(detail);
            }
        }

        List<CntrLog> cntrLogs = cntrLogService.getBaseMapper().selectList(new QueryWrapper<CntrLog>().eq("disable", 0)
                .eq("cntr_no", info.getOldCntrNo()).eq("order_no", info.getOrderNo()));
        if(cntrLogs.size()>0){
            for (CntrLog cntrLog : cntrLogs) {
                cntrLog.setCntrNo(info.getCntrNo());
                cntrLog.setCntrSize(info.getCntrSize());
                cntrLog.setGoods(info.getGoods());
                cntrLog.setSealNo(info.getSealNo());
                cntrLog.setConsigneePhone(info.getConsigneePhone());
                cntrLog.setWeightPred(info.getWeightPred());
                cntrLog.setEfFlag(info.getEfFlag());
                cntrLog.setConsignee(info.getConsignee());
                cntrLog.setConsigneeLx(info.getConsigneeLx());
            }
            cntrLogService.updateBatchById(cntrLogs);
        }
        VehicleReservation reservation = vehicleReservationMapper.selectOne(new QueryWrapper<VehicleReservation>().eq("order_no", info.getOrderNo()).eq("disable", 0)
                .and(wrapper -> wrapper.eq("cntr_no", info.getOldCntrNo()).or().eq("cntr_no_b", info.getOldCntrNo())));
        if(reservation!=null){
            if(StrUtil.isNotBlank(reservation.getCntrNo()) && reservation.getCntrNo().equals(info.getOldCntrNo())){
                reservation.setCntrNo(info.getCntrNo());
                reservation.setCntrSize(info.getCntrSize());
            }
            if(StrUtil.isNotBlank(reservation.getCntrNoB()) && reservation.getCntrNoB().equals(info.getOldCntrNo())){
                reservation.setCntrNoB(info.getCntrNo());
                reservation.setCntrSizeB(info.getCntrSize());
            }
            vehicleReservationMapper.updateById(reservation);
        }
        return ResultUtil.ok();
    }

    @Override
    public ResultUtil<T> delCntrInfo(String cntrNo) {
        CntrInfo info = getById(cntrNo);
        if(info.getStatus()==1){
            if(StringUtils.isNotEmpty(info.getCntrWorkRemark())
                    && !(FyEnum.DSL.getName().equals(info.getCntrWorkRemark()) || FyEnum.YSL.getName().equals(info.getCntrWorkRemark()))){
                return ResultUtil.build(ResultUtilCodeEnum.CNTR_IS_INYARD);
            }
        }
        CntrInfo cntrInfo = deleteCntrInfo(info);
        boolean b = updateById(cntrInfo);
        if(info.getStatus()==1){
            //删除 委托 信息
            List<YwOrderCntr> cntrList = ywOrderCntrMapper.selectList(new QueryWrapper<YwOrderCntr>().eq("disable", 0)
                    .eq("cntr_no", info.getCntrNo()).eq("tally_state", 0));
            if(cntrList.size()>0){
                for (YwOrderCntr ywOrderCntr : cntrList) {
                    ywOrderCntr.setDisable(1);
                    ywOrderCntrMapper.updateById(ywOrderCntr);
                }
            }
        }
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    private CntrInfo deleteCntrInfo(CntrInfo cntrInfo) {
        CntrInfo cntrInfo1=new CntrInfo();
        BeanUtils.copyProperties(cntrInfo,cntrInfo1);
        cntrInfo1.setCntrWorkRemark(null);
        cntrInfo1.setCntrWorkRemarkB(null);
        cntrInfo1.setStatus(1);
        cntrInfo1.setArea("");
        cntrInfo1.setBay("");
        cntrInfo1.setCntrRemark("");
        cntrInfo1.setStartPort("");
        cntrInfo1.setEndPort("");
        cntrInfo1.setSpecialWay("");
        cntrInfo1.setConsigneeLx("");
        cntrInfo1.setConsigneePhone("");
        cntrInfo1.setConsignee("");
        cntrInfo1.setConsigner("");
        cntrInfo1.setMdPort("");
        cntrInfo1.setZhPort("");
        cntrInfo1.setOrderNo("");
        cntrInfo1.setCarNo("");
        cntrInfo1.setRemark("");
        cntrInfo1.setSealNo("");
        cntrInfo1.setGoods("");
        cntrInfo1.setWeightPred(null);
        return cntrInfo1;
    }

    @Override
    public JSONObject getCntrBayInfo(CntrInfo cntrInfo) {
        List<CntrInfoVo> pageList = baseMapper.selectCntrBayInfo(cntrInfo);
        JSONObject jsonObject = new JSONObject();
        for (CntrInfoVo vo : pageList) {
            //TODO 待优化 目前只显示A
            if (StrUtil.isBlank(vo.getBay())) {
                continue;
            }else{
//                if(!"A".equals(vo.getBay().substring(0,1))){
//                    continue;
//                }
            }

            String[] bayArray = vo.getBay().split("-");
            if (bayArray.length < 4) {
                continue;
            }
            String x = bayArray[1];
            String y = bayArray[2];
            if (StrUtil.isNotBlank(x) && x.length() == 1 && Integer.parseInt(x, 36) < 10) {
                x = "0" + x;
            }
//            if (StrUtil.isNotBlank(y) && !y.matches("[a-zA-Z]")) {
//                if (Integer.parseInt(y) < 10 && y.length() == 2) {
                    if("8+".equals(y)){
                        y = y + "";
                    }else{
                        y = Integer.parseInt(y) + "";
                    }
//                } else {
//                    y = NumberToAZ.AZ(Integer.parseInt(y));
//                }
//            }
            jsonObject.put(bayArray[0] + "-" + x + "-" + y + "-" + bayArray[3],vo.getEfFlag());
        }
        return jsonObject;
    }

    @Override
    public List<CntrInfoVo> getCntrInfoAll(CntrInfoVo vo) {
        //detail表中已经存在的箱号 [其他装车班列已经选择的箱号]
        List<TrainPlanDetail> selectList = detailMapper.selectCntrList(vo);
        if (selectList!=null && !selectList.isEmpty()){
            vo.setCntrNoList(selectList.stream().map(TrainPlanDetail::getCntrNo).collect(Collectors.toList()));
        }

        List<String> selCntrNo = new ArrayList<>();

        //1.在场+未锁+未删除
        List<String> list1 = baseMapper.getCntrInfoAll1();
        //2.车辆预约 重进+空进 J 未进场(卡口未理货)
        List<String> list2 = vehicleReservationMapper.getCntrInfoAll2();
        //3.散改集 已进场   未回重导入的
        List<String> list3 = ywOrderCntrMapper.getCntrInfoAll3();
        selCntrNo.addAll(list1);
        selCntrNo.addAll(list2);
        vo.setCntrNoList1(selCntrNo);
        List<CntrInfoVo> rel = baseMapper.getAllCntrNoByZc(vo);
        for (CntrInfoVo infoVo : rel) {
            for (String cntrNo : list3) {
                if (infoVo.getCntrNo().equals(cntrNo)){
                    infoVo.setNoSelect(1);//已进场   未回重导入的    展示 但不能勾选
                }
            }
            for (String cntrNo : list2) {
                if (infoVo.getCntrNo().equals(cntrNo)){
                    infoVo.setNoSelect(2);//车辆预约  未进场(卡口未理货)   颜色区分 能勾选
                }
            }
            if (infoVo.getSendTransportState()==1){
                infoVo.setNoSelect(3);//取消发运  展示 但不能勾选
            }
            if(StringUtils.isNotEmpty(infoVo.getBay()) && infoVo.getBay().indexOf("待整改")!=-1){
                infoVo.setNoSelect(4);
            }
//            infoVo.setShipVia(ywOrderCntrMapper.getShipViaByCntrNo(infoVo.getCntrNo(),infoVo.getOrderNo()));//箱子所属业务发运状态
        }
        return rel;
    }

    @Override
    public List<String> getBayInfoBayArea(String area) {
        List<String> pageList = baseMapper.selectBayInfoBayAreaList(area);
        pageList.sort((a, b) -> a.compareTo(b));
        return pageList;
    }

    @Override
    public List<CntrInfoVo> selectCntrBybay(String bay) {
        return baseMapper.selectCntrBybay(bay);
    }

    @Override
    public ResultUtil<T> cntrDuiTally(CntrTallyVo cntrTallyVo) {

        DeclareCar declareCar = declareCarMapper.selectById(cntrTallyVo.getDeclareId());
        CntrInfo cntrInfo1=new CntrInfo();
        cntrInfo1.setBay(cntrTallyVo.getBay());
        cntrInfo1.setCntrNo(cntrTallyVo.getCntrNo());
        if(cntrTallyVo.getCntrNo().equals(declareCar.getCntrA())){
            cntrInfo1.setEfFlag(declareCar.getEfFlagA());
            cntrInfo1.setCntrSize(declareCar.getCntrSizeA());
        }
        if(cntrTallyVo.getCntrNo().equals(declareCar.getCntrB())){
            cntrInfo1.setEfFlag(declareCar.getEfFlagB());
            cntrInfo1.setCntrSize(declareCar.getCntrSizeB());
        }
        ResultUtil<T>  result = checkBay(cntrInfo1);
        if (result.getCode()!=200) {
            return result;
        }

        YwOrderCntr ywOrderCntr = ywOrderCntrMapper.selectById(cntrTallyVo.getId());
        if(ywOrderCntr!=null){
            if (ywOrderCntr.getTallyState() == 10) {
                return ResultUtil.build(400, "箱子" + cntrTallyVo.getCntrNo() + "已理货，请勿重复操作！");
            }
        }

        boolean istallEnd = false;
        YwOrder ywOrder=new YwOrder();
        if(ywOrderCntr!=null){
            ywOrder = ywOrderMapper.selectOne(new QueryWrapper<YwOrder>().eq("disable",0).eq("order_no",ywOrderCntr.getOrderNo()));
        }
        CntrInfo cntrInfo = baseMapper.selectById(cntrTallyVo.getCntrNo());


        if (StringUtils.isNotBlank(declareCar.getCntrA()) && StringUtils.isNotBlank(declareCar.getCntrB())) {
            // 2个箱子 只更新某一个箱子的状态
            if (cntrTallyVo.getCntrNo().equals(declareCar.getCntrA())) {
                declareCar.setTallyFlag(10);
                declareCar.setJhBaya(cntrTallyVo.getBay());
            } else if (cntrTallyVo.getCntrNo().equals(declareCar.getCntrB())) {
                declareCar.setTallyFlagB(10);
                declareCar.setJhBayb(cntrTallyVo.getBay());
            }
            //如果2个箱子最后一个箱子理货完成后才发送空车核放单
            if (declareCar.getTallyFlag() == 10 && declareCar.getTallyFlagB() == 10) {
                istallEnd = true;
            }
        } else {
            // 只存在一个箱子 2个状态都更新
            if (cntrTallyVo.getCntrNo().equals(declareCar.getCntrA())
                    || cntrTallyVo.getCntrNo().equals(declareCar.getCntrB())) {
                declareCar.setTallyFlag(10);
                declareCar.setTallyFlagB(10);
                declareCar.setJhBaya(cntrTallyVo.getBay());
                istallEnd=true;
            }
        }
        declareCarMapper.updateById(declareCar);


        QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("bay", cntrTallyVo.getBay());
        queryWrapper.eq("status", 0);
        if (baseMapper.selectCount(queryWrapper) > 0 && !(cntrTallyVo.getBay().matches(".*[\u4e00-\u9fa5]+.*"))) {
            return ResultUtil.build(ResultUtilCodeEnum.BAY_EXIST);
        }

        if (cntrInfo == null) {
            // 往库存新增一个箱子
            CntrInfo newC = new CntrInfo();
            // 组装cntrInfo
            CntrInfo c = assembleCntrInfo(newC, ywOrderCntr, ywOrder, cntrTallyVo, declareCar, 0);
            baseMapper.insert(c);
        } else {
            // 组装cntrInfo
            CntrInfo c = assembleCntrInfo(cntrInfo, ywOrderCntr, ywOrder, cntrTallyVo, declareCar, 0);
            if(c.getDisable()){
                c.setDisable(false);
            }
//            c.setLockFlag(0);//中控理货后 解锁
            baseMapper.updateById(cntrInfo);
        }

        if(ywOrderCntr!=null){
            ywOrderCntrMapper.update(null, Wrappers.<YwOrderCntr>lambdaUpdate()
                    .set(YwOrderCntr::getJhBay, cntrTallyVo.getBay())
                    .set(YwOrderCntr::getTallyState, 10)
                    .set(YwOrderCntr::getEfFlag, cntrTallyVo.getEfFlag())
                    .set(YwOrderCntr::getLhWeight,cntrTallyVo.getLhWeight())
                    .set(YwOrderCntr::getTallyTime, LocalDateTime.now())
                    .set(YwOrderCntr::getTallyUserId, cntrTallyVo.getUid())
                    .eq(YwOrderCntr::getId, ywOrderCntr.getId()));
        }


        DeclareCarVo declareCarVo=new DeclareCarVo();
        List<DeclareCarVo> txCarList = declareCarMapper.getTxCarList(declareCarVo);
        if(txCarList.size()>0){
            if(txCarList.stream().map(DeclareCarVo::getCarNo).collect(Collectors.toList()).contains(declareCar.getCarNo())){
                istallEnd=false;
            }
        }
        //关闭自动出卡
//        if (istallEnd) {
//            if(!(YwOrderTypeEnum.SGJ.getCode().equals(ywOrder.getOrderType()))){
//                if(declareCar.getVehicleIdB()!=null){
//                    VehicleReservation reservation = vehicleReservationMapper.selectById(declareCar.getVehicleIdB());
//                    if(reservation.getTallyFlag()==10 && reservation.getTallyFlagB() ==10){
//                        //自动出卡
//                        declareCarMapper.update(new DeclareCar(), Wrappers.<DeclareCar>lambdaUpdate()
//                                .eq(DeclareCar::getDisable, 0)
//                                .eq(DeclareCar::getCarNo, declareCar.getCarNo())
//                                .eq(DeclareCar::getId, declareCar.getId())
//                                .eq(DeclareCar::getOutType, 0)
//                                .set(DeclareCar::getOutType, 1)
//                                .set(DeclareCar::getVehicleId,declareCar.getVehicleId())
//                                .set(DeclareCar::getOutTime, LocalDateTime.now()));
//                        VehicleReservation reservation1 = vehicleReservationMapper.selectById(cntrTallyVo.getVehicleId());
//                        if(reservation1 != null){
//                            reservation1.setEndState(1);
//                            vehicleReservationMapper.updateById(reservation1);
//                        }
//                    }
//                }else{
//                    //自动出卡
//                    declareCarMapper.update(new DeclareCar(), Wrappers.<DeclareCar>lambdaUpdate()
//                            .eq(DeclareCar::getDisable, 0)
//                            .eq(DeclareCar::getCarNo, declareCar.getCarNo())
//                            .eq(DeclareCar::getId, declareCar.getId())
//                            .eq(DeclareCar::getOutType, 0)
//                            .set(DeclareCar::getVehicleId,declareCar.getVehicleId())
//                            .set(DeclareCar::getOutType, 1)
//                            .set(DeclareCar::getOutTime, LocalDateTime.now()));
//                    VehicleReservation reservation1 = vehicleReservationMapper.selectById(cntrTallyVo.getVehicleId());
//                    if(reservation1 != null){
//                        reservation1.setEndState(1);
//                        vehicleReservationMapper.updateById(reservation1);
//                    }
//                }
//            }else{
//                //自动出卡
//                declareCarMapper.update(new DeclareCar(), Wrappers.<DeclareCar>lambdaUpdate()
//                        .eq(DeclareCar::getDisable, 0)
//                        .eq(DeclareCar::getCarNo, declareCar.getCarNo())
//                        .eq(DeclareCar::getId, declareCar.getId())
//                        .eq(DeclareCar::getOutType, 0)
//                        .set(DeclareCar::getVehicleId,declareCar.getVehicleId())
//                        .set(DeclareCar::getOutType, 1)
//                        .set(DeclareCar::getOutTime, LocalDateTime.now()));
//            }
//        }
        return ResultUtil.build(200, "理货成功");
    }

    public CntrInfo assembleCntrInfo(CntrInfo cntrInfo, YwOrderCntr ywOrderCntr, YwOrder ywOrder,
                                     CntrTallyVo cntrTallyVo,DeclareCar declareCar, Integer status) {
        if (StrUtil.isBlank(cntrInfo.getCntrNo())) {
            cntrInfo.setCntrNo(cntrTallyVo.getCntrNo());
            cntrInfo.setCntrSize(cntrTallyVo.getCntrSize());
            cntrInfo.setDamagedFlag(0);
            cntrInfo.setCreatetime(LocalDateTime.now());
            cntrInfo.setDisable(false);
            cntrInfo.setUpdatetime(LocalDateTime.now());
        }
        if (declareCar != null) {
            if (cntrTallyVo.getCntrNo().equals(declareCar.getCntrA())) {
                cntrInfo.setXk(declareCar.getXkA());
                cntrInfo.setEfFlag(declareCar.getEfFlagA());
            } else if (cntrTallyVo.getCntrNo().equals(declareCar.getCntrB())) {
                cntrInfo.setXk(declareCar.getXkB());
                cntrInfo.setEfFlag(declareCar.getEfFlagB());
            }
            cntrInfo.setCarNo(declareCar.getCarNo());
        }
        if (status == 0) {
            cntrInfo.setBay(cntrTallyVo.getBay());
            if (cntrTallyVo.getBay().split("-").length > 0) {
                cntrInfo.setArea(cntrTallyVo.getBay().split("-")[0]);
            }
        } else if (status == 1) {
            cntrInfo.setBay("");
            cntrInfo.setArea("");
        }
        if(ywOrder!=null && ywOrderCntr!=null){
            if(YwOrderTypeEnum.ZJ.getCode().equals(ywOrder.getOrderType()) || YwOrderTypeEnum.SGJ.getCode().equals(ywOrder.getOrderType())){
                cntrInfo.setRemark("收箱理货("+YwOrderTypeEnum.ZJ.getName()+")");
            }else if(YwOrderTypeEnum.KJ.getCode().equals(ywOrder.getOrderType())){
                cntrInfo.setRemark("收箱理货("+YwOrderTypeEnum.KJ.getName()+")");
            }else if(YwOrderTypeEnum.HK.getCode().equals(ywOrder.getOrderType())){
                cntrInfo.setRemark("收箱理货("+YwOrderTypeEnum.HK.getName()+")");
            }

            cntrInfo.setOperateType("SXLH");
            cntrInfo.setTrackOrCar(1); //汽车
            cntrInfo.setPayer(ywOrderCntr.getPayer()); //付款人
            cntrInfo.setCompanyId(ywOrderCntr.getCompanyId());
            cntrInfo.setInTime(LocalDateTime.now());
            cntrInfo.setSealNo(ywOrderCntr.getSealNo());
            cntrInfo.setGoods(ywOrderCntr.getGoodsName());
            if(ywOrderCntr.getShipperWeight()!=null){
                cntrInfo.setWeightPred(Double.valueOf(ywOrderCntr.getShipperWeight()));
            }
            //散改集的箱子落场理货默认重箱
            if(YwOrderTypeEnum.SGJ.getCode().equals(ywOrder.getOrderType())){
                cntrInfo.setEfFlag("F");
            }else{
//                cntrInfo.setEfFlag(ywOrderCntr.getEfFlag());
            }
            cntrInfo.setStatus(status);
            cntrInfo.setBillNo(ywOrderCntr.getBillNo());
            if (StrUtil.isNotBlank(ywOrderCntr.getWeight())) {
                cntrInfo.setWeightPred(Double.valueOf(ywOrderCntr.getWeight()));
            }
            cntrInfo.setStatus(status);
            cntrInfo.setUserId(cntrTallyVo.getUid());
            cntrInfo.setMemberId(cntrTallyVo.getMid());
            cntrInfo.setUserName(cntrTallyVo.getUserName());
            cntrInfo.setAccesspath(cntrTallyVo.getAccesspath());
            cntrInfo.setDeviceNo(cntrTallyVo.getDeviceNo());
            cntrInfo.setMachineCode(cntrTallyVo.getMachineCode());
            cntrInfo.setMachineName(cntrTallyVo.getMachineName());
            cntrInfo.setDriverName(cntrTallyVo.getDriverName());
            cntrInfo.setUpdatetime(LocalDateTime.now());
            cntrInfo.setOrderNo(ywOrder.getOrderNo());
            //股道 顺位号 托运人 承运人重量 发货人 收货人
            cntrInfo.setStrands(ywOrderCntr.getTrack());
            if(StringUtils.isNotEmpty(ywOrderCntr.getCisNo())){
                cntrInfo.setSwId(Integer.valueOf(ywOrderCntr.getCisNo()));
            }
            if(StringUtils.isNotEmpty(ywOrderCntr.getShipperWeight())){
                cntrInfo.setShipperWeight(Integer.valueOf(ywOrderCntr.getShipperWeight()));
            }
            if(StringUtils.isNotEmpty(ywOrderCntr.getCarrierWeight())){
                cntrInfo.setCarrierWeight(Integer.valueOf(ywOrderCntr.getCarrierWeight()));
            }
            cntrInfo.setConsigner(ywOrderCntr.getShipper());
            cntrInfo.setConsignee(ywOrderCntr.getConsignee());
            //船名 卸货港 起运港 收货人电话 收货联系人 发站 到站
            cntrInfo.setShipName(ywOrder.getShipName());
            cntrInfo.setXPort(ywOrder.getXPort());
            cntrInfo.setQyPort(ywOrder.getQyPort());
            cntrInfo.setConsigneePhone(ywOrder.getConsigneePhone());
            cntrInfo.setConsigneeLx(ywOrder.getConsigneeLx());
            cntrInfo.setStartPort(ywOrder.getStartPort());
            cntrInfo.setEndPort(ywOrder.getEndPort());
            cntrInfo.setLhWeight(cntrTallyVo.getLhWeight());
            cntrInfo.setCntrWorkRemark(FyEnum.YJC.getName());
            if(StringUtils.isNotEmpty(cntrTallyVo.getBay()) && "待整改区".equals(cntrTallyVo.getBay())){
                cntrInfo.setRemark("收箱理货(待整改)");
                cntrInfo.setOperateType("SXLHDZG");
                cntrInfo.setLockFlag(1);
                cntrInfo.setLockStart(LocalDateTime.now());
                cntrInfo.setLockRemark("待整改");
                cntrInfo.setCntrWorkRemark(FyEnum.DZG.getName());
            }
            //保存箱动态
            CntrLog cntrLog = new CntrLog();
            BeanUtils.copyProperties(cntrInfo, cntrLog);
            if (declareCar != null) {
                cntrLog.setVehicleReservationId(declareCar.getVehicleId());
            }
            cntrLog.setZhPort(ywOrder.getQyPort());
            cntrLog.setMdPort(ywOrder.getXPort());
            cntrLog.setCreatetime(LocalDateTime.now());
            cntrLog.setId(null);
            cntrLogMapper.insert(cntrLog);
        }else{
            cntrInfo.setOperateType("SXLH");
            cntrInfo.setTrackOrCar(1); //汽车
            cntrInfo.setInTime(LocalDateTime.now());
            //散改集的箱子落场理货默认重箱
            cntrInfo.setEfFlag(cntrTallyVo.getEfFlag());
            cntrInfo.setRemark("收箱理货");
            cntrInfo.setStatus(status);
            cntrInfo.setUserId(cntrTallyVo.getUid());
            cntrInfo.setMemberId(cntrTallyVo.getMid());
            cntrInfo.setUserName(cntrTallyVo.getUserName());
            cntrInfo.setAccesspath(cntrTallyVo.getAccesspath());
            cntrInfo.setDeviceNo(cntrTallyVo.getDeviceNo());
            cntrInfo.setMachineCode(cntrTallyVo.getMachineCode());
            cntrInfo.setMachineName(cntrTallyVo.getMachineName());
            cntrInfo.setDriverName(cntrTallyVo.getDriverName());
            cntrInfo.setLockFlag(1);
            cntrInfo.setLockStart(LocalDateTime.now());
            cntrInfo.setUpdatetime(LocalDateTime.now());
            cntrInfo.setLhWeight(cntrTallyVo.getLhWeight());
            cntrInfo.setCntrWorkRemark(FyEnum.YJC.getName());
            if(StringUtils.isNotEmpty(cntrTallyVo.getBay()) && "待整改区".equals(cntrTallyVo.getBay())){
                cntrInfo.setRemark("收箱理货(待整改)");
                cntrInfo.setOperateType("SXLHDZG");
                cntrInfo.setLockFlag(1);
                cntrInfo.setLockStart(LocalDateTime.now());
                cntrInfo.setLockRemark("待整改");
                cntrInfo.setCntrWorkRemark(FyEnum.DZG.getName());
            }
            //保存箱动态
            CntrLog cntrLog = new CntrLog();
            BeanUtils.copyProperties(cntrInfo, cntrLog);
            cntrLog.setCreatetime(LocalDateTime.now());
            cntrLog.setId(null);
            cntrLogMapper.insert(cntrLog);
        }
        return cntrInfo;
    }

    @Override
    public List<CntrInfo> getIpadZcCntrInfoByBay(CntrInfoVo vo) {
        return baseMapper.getIpadZcCntrInfoByBay(vo);
    }

    @Override
    public List<CntrInfo> getIpadgetAllCntr(String cntrNo) {
        QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("disable", 0);
        queryWrapper.eq("status", 0);
        if (StrUtil.isNotBlank(cntrNo)) {
            queryWrapper.like("cntr_no", cntrNo);
        }
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<CntrInfo> getAfter(String after) {
        QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<CntrInfo>();
        queryWrapper.eq("status", 0);
        queryWrapper.like("bay", after);
        queryWrapper.eq("disable", 0);
        queryWrapper.orderByAsc("bay");
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public List<CntrInfo> getBefore(String before) {
        QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<CntrInfo>();
        queryWrapper.eq("status", 0);
        queryWrapper.like("bay", before);
        queryWrapper.eq("disable", 0);
        queryWrapper.orderByAsc("bay");
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public ResultUtil<T> cntrMoveBay(CntrTallyVo cntrTallyVo) {
        String cntrNo = cntrTallyVo.getCntrNo();
        CntrInfo cntr = getByCntrNo(cntrNo);
        // 贝位校验
        cntr.setBay(cntrTallyVo.getBay());
        ResultUtil<T> resultUtil = checkBay(cntr);
        if (resultUtil.getCode()!=200){
            return resultUtil;
        }
        if (StrUtil.isNotBlank(cntrTallyVo.getBay())) {
            cntr.setArea(cntrTallyVo.getBay().split("-")[0]);
        } else {
            cntr.setArea("");
        }
//        cntr.setBay(cntrTallyVo.getBay());
        cntr.setAccesspath(cntrTallyVo.getAccesspath());
        cntr.setDeviceNo(cntrTallyVo.getDeviceNo());
        cntr.setDriverName(cntrTallyVo.getDriverName());
        cntr.setMachineCode(cntrTallyVo.getMachineCode());
        cntr.setMachineName(cntrTallyVo.getMachineName());
        cntr.setMoveReason(cntrTallyVo.getMoveReason());

        cntr.setRemark("移箱");
        cntr.setOperateType("MCBAY");
        int b = baseMapper.updateById(cntr);
        //保存箱动态
        CntrLog cntrLog = new CntrLog();
        BeanUtils.copyProperties(cntr, cntrLog);
        cntrLog.setCarNo(null);
        cntrLog.setCreatetime(LocalDateTime.now());
        cntrLog.setId(null);
        cntrLogMapper.insert(cntrLog);
        if (b == 1) {
           return ResultUtil.ok();
        }
        return ResultUtil.fail();
    }

    @Override
    public CntrInfo getByCntrNo(String cntrNo) {
        QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<CntrInfo>();
        if (StrUtil.isNotBlank(cntrNo)) {
            queryWrapper.eq("cntr_no", cntrNo);
        }
        List<CntrInfo> cntrlist = baseMapper.selectList(queryWrapper);
        if (!cntrlist.isEmpty()) {
            return cntrlist.get(0);
        }
        return null;
    }

    @Override
    public ResultUtil<T> cntrXcTally(CntrTallyVo cntrTallyVo) {

        TrainPlanDetail trainPlanDetail = detailMapper.selectById(cntrTallyVo.getId());//卸车清单表信息
        //贝位处理
        if (cntrTallyVo.getArea().contains("整改")){//区域
            cntrTallyVo.setArea("待整改区");
            cntrTallyVo.setBay("");//空贝
        }else{
            if ("E".equals(cntrTallyVo.getEfFlag())){//空箱-洗箱区
                cntrTallyVo.setArea("洗箱区");
            }else{//贝位
                CntrInfo cntrInfo1=new CntrInfo();
                cntrInfo1.setBay(cntrTallyVo.getBay());
                cntrInfo1.setCntrNo(cntrTallyVo.getCntrNo());
                cntrInfo1.setEfFlag(trainPlanDetail.getEfFlag());
                cntrInfo1.setCntrSize(trainPlanDetail.getCntrSize());
                ResultUtil<T>  result = checkBay(cntrInfo1);
                if (result.getCode()!=200) {
                    return result;
                }
            }
        }

        if (trainPlanDetail.getTallyFlag() == 1) {
            return ResultUtil.build(400, "箱子" + cntrTallyVo.getCntrNo() + "已理货，请勿重复操作！");
        }

        TrainPlan trainPlan = trainPlanMapper.selectByTrainPlanNo(cntrTallyVo.getTrainPlanNo());
        CntrInfo cntrInfo = baseMapper.selectById(cntrTallyVo.getCntrNo());
        if(StringUtils.isNotEmpty(cntrTallyVo.getConsigner())){
            CompanyInfo companyInfo = companyInfoMapper.getCompanyIdByName(cntrTallyVo.getConsigner());
            if(companyInfo != null){
                cntrTallyVo.setCompanyId(companyInfo.getId());//卸车set发货人公司id
            }
        }
//        if ("A".equals(cntrTallyVo.getArea())){//正常区域
            QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("bay", cntrTallyVo.getBay());
            queryWrapper.eq("status", 0);
            if (baseMapper.selectCount(queryWrapper) > 0) {
                return ResultUtil.build(ResultUtilCodeEnum.BAY_EXIST);
            }
//        }
        //修改cntr_info理货状态
        if (cntrInfo == null) {
            // 往库存新增一个箱子
            CntrInfo newC = new CntrInfo();
            // 组装cntrInfo
            CntrInfo c = assembleCntrXcInfo(newC, trainPlanDetail, trainPlan, cntrTallyVo , 0);

            baseMapper.insert(c);
        } else {
            // 组装cntrInfo(修改理货状态)
            CntrInfo c = assembleCntrXcInfo(cntrInfo, trainPlanDetail, trainPlan, cntrTallyVo, 0);
            if(c.getDisable()){
                c.setDisable(false);
            }
            baseMapper.updateById(cntrInfo);
        }
        TrainPlan plan = trainPlanMapper.getByTrainPlanNo(cntrTallyVo.getTrainPlanNo());
        //修改计划清单表理货状态
        detailMapper.update(null, Wrappers.<TrainPlanDetail>lambdaUpdate()
                .set(TrainPlanDetail::getBay, cntrTallyVo.getBay())//贝位
                .set(TrainPlanDetail::getArea,cntrTallyVo.getArea())//区域
                .set(TrainPlanDetail::getTallyFlag, 1)
                .set(TrainPlanDetail::getTrainNumber, cntrTallyVo.getCarNo())
                .set(TrainPlanDetail::getZxTime,LocalDateTime.now())
                .set(TrainPlanDetail::getTallyUserId, cntrTallyVo.getUserId())
                .set(TrainPlanDetail::getMemberId,cntrTallyVo.getMid())
                .set(TrainPlanDetail::getTallyUserName,cntrTallyVo.getUserName())
                .set(TrainPlanDetail::getPlanId,plan.getId())//选择的卸车计划
                .eq(TrainPlanDetail::getId, trainPlanDetail.getId()));
        return ResultUtil.build(200, "理货成功");
    }

    @Override
    public List<CntrStatisticsVo> getComCntrList(CntrStatisticsVo vo) {
        List<CntrStatisticsVo> voList = baseMapper.selectComCntrList(vo);
        List<CntrStatisticsVo> result = new ArrayList<>();
        List<String> companys = voList.stream().map(CntrStatisticsVo::getCompanyName).distinct().collect(Collectors.toList());
        CntrStatisticsVo res;
        for (String company : companys) {
            res = new CntrStatisticsVo();
            res.setCompanyName(company);
            res.setEmpty2(voList.stream().filter(s -> company.equals(s.getCompanyName()) && s.getCntrSize().startsWith("2") && "E".equals(s.getEfFlag())).map(CntrStatisticsVo::getCntrNum).reduce(Integer::sum).orElse(0));
            res.setEmpty4(voList.stream().filter(s -> company.equals(s.getCompanyName()) && s.getCntrSize().startsWith("4") && "E".equals(s.getEfFlag())).map(CntrStatisticsVo::getCntrNum).reduce(Integer::sum).orElse(0));
            res.setEmptyTotal(res.getEmpty2() + res.getEmpty4());
            res.setFull2(voList.stream().filter(s -> company.equals(s.getCompanyName()) && s.getCntrSize().startsWith("2") && "F".equals(s.getEfFlag())).map(CntrStatisticsVo::getCntrNum).reduce(Integer::sum).orElse(0));
            res.setFull4(voList.stream().filter(s -> company.equals(s.getCompanyName()) && s.getCntrSize().startsWith("4") && "F".equals(s.getEfFlag())).map(CntrStatisticsVo::getCntrNum).reduce(Integer::sum).orElse(0));
            res.setFullTotal(res.getFull2() + res.getFull4());
            res.setTotalNum(res.getEmptyTotal() + res.getFullTotal());
            result.add(res);
        }
        return result;
    }

    private final static String EXPORT_EXCEL_PATH = "static/download/在场箱货主统计导出.xlsx";

    @Override
    public void exportComCntr(HttpServletRequest request, HttpServletResponse response, CntrStatisticsVo vo) {
        List<CntrStatisticsVo> vos = getComCntrList(vo);
        Map<String, Object> map = new HashMap<>();
        map.put("list", vos);
        map.put("empty2", vos.stream().map(CntrStatisticsVo::getEmpty2).reduce(Integer::sum).orElse(0));
        map.put("empty4", vos.stream().map(CntrStatisticsVo::getEmpty4).reduce(Integer::sum).orElse(0));
        map.put("emptyTotal", vos.stream().map(CntrStatisticsVo::getEmptyTotal).reduce(Integer::sum).orElse(0));
        map.put("full2", vos.stream().map(CntrStatisticsVo::getFull2).reduce(Integer::sum).orElse(0));
        map.put("full4", vos.stream().map(CntrStatisticsVo::getFull4).reduce(Integer::sum).orElse(0));
        map.put("fullTotal", vos.stream().map(CntrStatisticsVo::getFullTotal).reduce(Integer::sum).orElse(0));
        map.put("totalNum", vos.stream().map(CntrStatisticsVo::getTotalNum).reduce(Integer::sum).orElse(0));
        TemplateExportParams params = new TemplateExportParams(EXPORT_EXCEL_PATH);
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        FileExcelUtil.downloadExcelIo(workbook, request, response, "在场箱货主统计");
    }

    @Override
    public List<JSONObject> getZcEfCountCensus() {
        List<JSONObject> array = new ArrayList<>();
        List<CntrInfoVo> cntrInfos = baseMapper.selectZcEfCountCensus();
        Integer zxNum = 0;
        Integer kxNum = 0;
        for (CntrInfoVo cntrInfoVo : cntrInfos) {
            if (("F").equals(cntrInfoVo.getEfFlag())) {
                zxNum += cntrInfoVo.getNum();
            } else if (("E").equals(cntrInfoVo.getEfFlag())) {
                kxNum += cntrInfoVo.getNum();
            }
        }
        JSONObject jsonObjectzx = new JSONObject();
        jsonObjectzx.put("name", "重箱");
//        jsonObjectzx.put("selected", true);
//        jsonObjectzx.put("sliced", true);
        jsonObjectzx.put("value", zxNum);
        array.add(jsonObjectzx);
        JSONObject jsonObjectkx = new JSONObject();
        jsonObjectkx.put("name", "空箱");
//        jsonObjectkx.set("selected", true);
        jsonObjectkx.put("value", kxNum);
        array.add(jsonObjectkx);
        return array;
    }

    @Override
    public List<JSONObject> getZcSizeCensus() {
        List<JSONObject> array = new ArrayList<>();
        List<CntrInfoVo> cntrInfos = baseMapper.selectZcSizeCensus();
        Integer dxNum = 0;
        Integer xxNum = 0;
        for (CntrInfoVo cntrInfoVo : cntrInfos) {
            if (StrUtil.isNotBlank(cntrInfoVo.getCntrSize())
                    && Integer.parseInt(cntrInfoVo.getCntrSize().substring(0, 2)) >= 40) {
                dxNum += cntrInfoVo.getNum();
            } else if (StrUtil.isNotBlank(cntrInfoVo.getCntrSize())
                    && Integer.parseInt(cntrInfoVo.getCntrSize().substring(0, 1)) < 40) {
                xxNum += cntrInfoVo.getNum();
            }
        }
        JSONObject jsonObjectdx = new JSONObject();
        JSONObject jsonObjectxx = new JSONObject();
        jsonObjectdx.put("name", "大箱");
//        jsonObjectdx.put("selected", true);
        jsonObjectdx.put("value", dxNum);
        array.add(jsonObjectdx);
        jsonObjectxx.put("name", "小箱");
//        jsonObjectxx.put("selected", true);
//        jsonObjectxx.put("sliced", true);
        jsonObjectxx.put("value", xxNum);
        array.add(jsonObjectxx);
        return array;
    }

    @Override
    public List<CntrInfo> getOnRoadList(CntrInfoVo vo) {
        // 查询堆场箱，获取bay
        CntrInfo cntrInfo = baseMapper.selectOne(new LambdaQueryWrapper<CntrInfo>().eq(CntrInfo::getCntrNo, vo.getCntrNo()).eq(CntrInfo::getStatus, 0));
        if (cntrInfo == null) {
            return new ArrayList<>();
        }
        String bay = cntrInfo.getBay();
        if (StrUtil.isBlank(bay)) {
            return new ArrayList<>();
        }

        // 查询层数
        String[] split = bay.split("-");
        String layer = split[split.length - 1];
        vo.setLayer(layer);
        vo.setBay(cntrInfo.getBay());
        return baseMapper.getOnRoadList(vo);

    }

    @Override
    public JSONObject getYardCntrStatistic(CntrInfo cntrInfo) {
        List<StorehouseVo> storehouseList = baseMapper.getCntrTypeNumByArea(cntrInfo.getArea());
        Map<List<String>, Integer> map = new HashMap<List<String>, Integer>();
        for (StorehouseVo vo : storehouseList) {
            if (vo.getArea() == null)
                continue;
            List<String> type = new ArrayList<String>();
            type.add(vo.getArea());
            type.add(getCntrType(vo.getCntrSize().trim()));
            type.add(vo.getEfFlag());
            if (map.containsKey(type)) {
                map.put(type, map.get(type) + vo.getNum());
            } else {
                map.put(type, vo.getNum());
            }
            List<String> total = new ArrayList<String>();
            total.add("total");
            total.add(getCntrType(vo.getCntrSize().trim()));
            total.add(vo.getEfFlag());
            if (map.containsKey(total)) {
                map.put(total, map.get(total) + vo.getNum());
            } else {
                map.put(total, vo.getNum());
            }
        }
        JSONObject jsonObject = new JSONObject();
        for (List<String> key : map.keySet()) {
            if (jsonObject.containsKey(key.get(0))) {
                JSONObject areaObject = jsonObject.getJSONObject(key.get(0));
                JSONObject typeObject;
                if (areaObject.containsKey(key.get(1))) {
                    typeObject = areaObject.getJSONObject(key.get(1));
                    typeObject.put(key.get(2), map.get(key));
                    typeObject.put("total", typeObject.getIntValue("total") + map.get(key));
                } else {
                    typeObject = new JSONObject();
                    typeObject.put(key.get(2), map.get(key));
                    typeObject.put("total", map.get(key));
                }
                areaObject.put(key.get(1), typeObject);
                jsonObject.put(key.get(0), areaObject);
            } else {
                JSONObject areaObject = new JSONObject();
                JSONObject typeObject = new JSONObject();
                typeObject.put(key.get(2), map.get(key));
                typeObject.put("total", map.get(key));
                areaObject.put(key.get(1), typeObject);
                jsonObject.put(key.get(0), areaObject);
            }
        }
        return jsonObject;
    }

    @Override
    public List<CntrInfoVo> getAppCntrList(Page<CntrInfoVo> page, CntrInfoVo vo) {
        IPage<CntrInfoVo> iPage = baseMapper.getAllList(page,vo);
        return iPage.getRecords();
    }

    @Override
    public Map<String, Object> dataCntrAnaly() {
        List<CntrInfo> cntrInfos = baseMapper.selectList(new QueryWrapper<CntrInfo>().eq("disable", 0).eq("status", 0));
        Map<String, Object> returnMap = new HashMap<>();
        Integer total = 0;
        Integer totalTeu = 0;
        Integer big = 0;
        Integer bigTeu = 0;
        Integer small = 0;
        Integer smallTeu = 0;
        Integer empty = 0;
        Integer emptyTeu = 0;
        Integer heavy = 0;
        Integer heavyTeu = 0;
        Integer nm = 0;
        Integer nmTeu = 0;
        Integer wm = 0;
        Integer wmTeu = 0;

        for (CntrInfo cntrInfo : cntrInfos) {
            // 判断大小类型
            if (cntrInfo.getCntrSize().startsWith("4")) {
                total++;
                totalTeu += 2;
                big++;
                bigTeu += 2;
                // 判断是否为空
                if ("E".equals(cntrInfo.getEfFlag())) {
                    empty++;
                    emptyTeu += 2;
                } else {
                    heavy++;
                    heavyTeu += 2;
                }

                // 判断贸易类型
                if ("W".equals(cntrInfo.getTradeType())) {
                    wm++;
                    wmTeu += 2;
                } else {
                    nm++;
                    nmTeu += 2;
                }
            } else {
                total++;
                totalTeu += 1;
                small++;
                smallTeu += 1;
                // 判断是否为空
                if ("E".equals(cntrInfo.getEfFlag())) {
                    empty++;
                    emptyTeu += 1;
                } else {
                    heavy++;
                    heavyTeu += 1;
                }

                // 判断贸易类型
                if ("W".equals(cntrInfo.getTradeType())) {
                    wm++;
                    wmTeu += 1;
                } else {
                    nm++;
                    nmTeu += 1;
                }
            }
        }
        returnMap.put("total",total);
        returnMap.put("totalTeu",totalTeu);
        returnMap.put("big",big);
        returnMap.put("bigTeu",bigTeu);
        returnMap.put("small",small);
        returnMap.put("smallTeu",smallTeu);
        returnMap.put("empty",empty);
        returnMap.put("emptyTeu",emptyTeu);
        returnMap.put("heavy",heavy);
        returnMap.put("heavyTeu",heavyTeu);
        returnMap.put("wm",wm);
        returnMap.put("wmTeu",wmTeu);
        returnMap.put("nm",nm);
        returnMap.put("nmTeu",nmTeu);
        return returnMap;
    }

    @Override
    public List<CntrInfoVo> getLockCntrList() {
        IPage<CntrInfoVo> iPage = baseMapper.getLockCntrList();
        return iPage.getRecords();
    }

    @Override
    public ResultUtil<T> lockCntr(List<CntrInfo> cntrInfos,String lockRemark) {
        LocalDateTime now = LocalDateTime.now();
        List<CntrLog> cntrLogList=new ArrayList<>();
        for(CntrInfo c:cntrInfos){
            CntrLog log = new CntrLog();
            c.setLockFlag(1);
            c.setLockStart(LocalDateTime.now());//上锁时间
            c.setLockRemark(lockRemark);//上锁备注
            BeanUtils.copyProperties(c,log);
            log.setRemark("锁箱");
            log.setLockRemark(lockRemark);
            log.setCreatetime(now);
            cntrLogList.add(log);
        }

        boolean b = updateBatchById(cntrInfos);
        cntrLogService.saveBatch(cntrLogList);
        if (b){
            return ResultUtil.ok();
        }
        return ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> unLockCntr(List<CntrInfo> cntrInfos) {
        LocalDateTime now = LocalDateTime.now();
        List<CntrLog> cntrLogList=new ArrayList<>();
        for(CntrInfo c:cntrInfos){
            CntrLog log = new CntrLog();
            c.setLockFlag(0);
            c.setLockEnd(LocalDateTime.now());//解锁时间
            BeanUtils.copyProperties(c,log);
            log.setRemark("解锁箱");
            log.setCreatetime(now);
            cntrLogList.add(log);
        }
        boolean b = updateBatchById(cntrInfos);
        cntrLogService.saveBatch(cntrLogList);
        if (b){
            return ResultUtil.ok();
        }
        return ResultUtil.fail();
    }

    @Override
    public List<CntrInfo> getSgjYwCntrList( CarInfoVo vo) {
        return baseMapper.getSgjYwCntrList(vo);
    }

    private String getCntrType(String cntrType) {
        return Integer.parseInt(cntrType.replaceAll("[A-Za-z]", "")) > 30 ? "big" : "small";
    }

    public CntrInfo assembleCntrXcInfo(CntrInfo cntrInfo, TrainPlanDetail trainPlanDetail, TrainPlan trainPlan,
                                     CntrTallyVo cntrTallyVo,Integer status) {
        if (StrUtil.isBlank(cntrInfo.getCntrNo())) {
            cntrInfo.setCntrNo(trainPlanDetail.getCntrNo());
            cntrInfo.setCntrSize(trainPlanDetail.getCntrSize());
            cntrInfo.setDamagedFlag(0);
            cntrInfo.setCreatetime(LocalDateTime.now());
            cntrInfo.setDisable(false);
            cntrInfo.setUpdatetime(LocalDateTime.now());
        }
        cntrInfo.setCarNo(trainPlanDetail.getCarNo());
        if (status == 0) {//卸车
//            if ("A".equals(cntrTallyVo.getArea())){//非区域
                cntrInfo.setBay(cntrTallyVo.getBay());
                if (cntrTallyVo.getBay().split("-").length > 0) {//A-01-01-1
                    cntrInfo.setArea(cntrTallyVo.getBay().split("-")[0]);
                }
//            }
        } else if (status == 1) {//装车
            cntrInfo.setBay("");
            cntrInfo.setArea("");
        }
        cntrInfo.setArea(cntrTallyVo.getArea());
        cntrInfo.setRemark("卸车理货(入场)");
        cntrInfo.setOperateType("XCLH");
        if (cntrTallyVo.getArea().contains("整改")){
            cntrInfo.setRemark("卸车理货(待整改)");
            cntrInfo.setOperateType("XCLHDZG");
            cntrInfo.setCntrWorkRemarkB(DdEnum.DZG.getName());
            cntrInfo.setLockFlag(1);
            cntrInfo.setLockStart(LocalDateTime.now());
            cntrInfo.setLockRemark("待整改");
        }else{
            cntrInfo.setCntrWorkRemarkB(DdEnum.YLC.getName());
        }
        cntrInfo.setTrackOrCar(0); // 来源火车
        cntrInfo.setCompanyId(cntrTallyVo.getCompanyId());//卸车公司id
        cntrInfo.setInTime(LocalDateTime.now());
        cntrInfo.setSealNo(trainPlanDetail.getSealNo());
        cntrInfo.setGoods(trainPlanDetail.getGoods());
        if(trainPlanDetail.getShipperWeight()!=null){
            cntrInfo.setWeightPred(Double.valueOf(trainPlanDetail.getShipperWeight()));
        }
        cntrInfo.setEfFlag(trainPlanDetail.getEfFlag());
        cntrInfo.setStatus(status);
        cntrInfo.setBillNo(trainPlanDetail.getBillNo());
        if (trainPlanDetail.getWeightPred()!=null) {
            cntrInfo.setWeightPred(trainPlanDetail.getWeightPred());
        }
        cntrInfo.setEfFlag(trainPlanDetail.getEfFlag());
        cntrInfo.setStatus(status);
        cntrInfo.setUserId(cntrTallyVo.getUserId());
        cntrInfo.setMemberId(cntrTallyVo.getMid());
        cntrInfo.setUserName(cntrTallyVo.getUserName());
        cntrInfo.setAccesspath(cntrTallyVo.getAccesspath());
        cntrInfo.setDeviceNo(cntrTallyVo.getDeviceNo());
        cntrInfo.setMachineCode(cntrTallyVo.getMachineCode());
        cntrInfo.setMachineName(cntrTallyVo.getMachineName());
        cntrInfo.setDriverName(cntrTallyVo.getDriverName());
        cntrInfo.setUpdatetime(LocalDateTime.now());
        cntrInfo.setOrderNo(trainPlan.getTrainPlanNo());
        //股道 顺位号 托运人 承运人重量 发货人 收货人
        cntrInfo.setStrands(trainPlanDetail.getStrands());
        if(trainPlanDetail.getSwId()!=null){
            cntrInfo.setSwId(trainPlanDetail.getSwId());
        }
        if(trainPlanDetail.getShipperWeight()!=null){
            cntrInfo.setShipperWeight(trainPlanDetail.getShipperWeight());
        }
        if(trainPlanDetail.getCarrierWeight()!=null){
            cntrInfo.setCarrierWeight(trainPlanDetail.getCarrierWeight());
        }
        cntrInfo.setConsigner(trainPlanDetail.getConsigner());
        cntrInfo.setConsignee(trainPlanDetail.getConsignee());
        cntrInfo.setPayer(trainPlanDetail.getConsignee());
        cntrInfo.setEndPort(trainPlanDetail.getMdPort());
        cntrInfo.setStartPort(trainPlanDetail.getZhPort());


//        if(StringUtils.isNotEmpty(cntrTallyVo.getBay()) && "待整改区".equals(cntrTallyVo.getBay())){
//            cntrInfo.setRemark("卸车理货(待整改)");
//            cntrInfo.setLockFlag(1);
//            cntrInfo.setLockStart(LocalDateTime.now());
//            cntrInfo.setLockRemark("待整改");
//        }
        //保存箱动态
        CntrLog cntrLog = new CntrLog();
        BeanUtils.copyProperties(cntrInfo, cntrLog);
        cntrLog.setCreatetime(LocalDateTime.now());
        cntrLog.setId(null);
        cntrLogMapper.insert(cntrLog);
        return cntrInfo;
    }
    @Override
    public JSONObject getCntrInfo(CntrInfo info) {
        List<DianZiCangWeiTuVo> list1 = baseMapper.getOverDateYardinfo(info);
        List<DianZiCangWeiTuVo> list2 = baseMapper.getAreaYardinfo(info);
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("overDateCntr",list1);
        jsonObject.put("storageAreaCntr",list2);
        return jsonObject;
    }

    @Override
    public JSONObject getIpadCntrInfo(CntrInfo cntrInfo) {
        List<DianZiCangWeiTuVo> list2 = baseMapper.getAreaYardinfo(cntrInfo);
        JSONObject jsonObject=new JSONObject();
        List<DianZiCangWeiTuVo> collect = list2.stream().filter(s -> !"A".equals(s.getTitleName())).collect(Collectors.toList());
        jsonObject.put("storageAreaCntr",collect);
        return jsonObject;
    }

    @Override
    public List<CntrInfoVo> getCntrB(CntrInfoVo vo) {
        return baseMapper.getCntrB(vo);
    }

    @Override
    public ResultUtil<T> changeLhWeight(CntrInfoVo cntrInfoVo) {
        CntrInfo cntrInfo = baseMapper.selectById(cntrInfoVo.getCntrNo());
        cntrInfo.setLhWeight(cntrInfoVo.getLhWeight());
        boolean b = updateById(cntrInfo);
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> addTxCntr(CntrInfoVo vo) {
        CntrInfo cntrInfo = baseMapper.selectById(vo.getCntrNo());
        if(cntrInfo==null){
            cntrInfo =new CntrInfo();
            BeanUtils.copyProperties(vo,cntrInfo);
            ResultUtil<T> resultUtil = checkBay(cntrInfo);
            if (resultUtil.getCode()!=200){
                return resultUtil;
            }
            cntrInfo.setInTime(LocalDateTime.now());
            cntrInfo.setIsZt(1);//允许不校验付款人直接提箱
            cntrInfo.setCntrWorkRemarkB(DdEnum.YLC.getName());
            cntrInfo.setCreatetime(LocalDateTime.now());
            cntrInfo.setStatus(0);
        }else {
            BeanUtils.copyProperties(vo,cntrInfo);
            ResultUtil<T> resultUtil = checkBay(cntrInfo);
            if (resultUtil.getCode()!=200){
                return resultUtil;
            }
            cntrInfo.setInTime(LocalDateTime.now());
            cntrInfo.setIsZt(1);//允许不校验付款人直接提箱
            cntrInfo.setCntrWorkRemarkB(DdEnum.YLC.getName());
            cntrInfo.setCreatetime(LocalDateTime.now());
            cntrInfo.setStatus(0);
        }
        boolean b = saveOrUpdate(cntrInfo);
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    @Override
    public List<CntrInfo> getOnAreaCntrList() {
        QueryWrapper<CntrInfo> queryWrapper = new QueryWrapper<CntrInfo>();
        queryWrapper.eq("status", 0);
        List<CntrInfo> cntrInfos = baseMapper.selectList(queryWrapper);
        // 待处理的还有目的港和二程船待完善
        return cntrInfos;
    };

    @Override
    public ResultUtil<T> cntrXcTallyZt(CntrTallyVo vo) {
        TrainPlanDetail detail = detailMapper.getById(vo.getId());
        if(StringUtils.isNotEmpty(vo.getYwOrderNo())){
            vo.setOrderNo(vo.getYwOrderNo());
        }
        //修改委托表  箱状态
        YwOrderCntr ywOrderCntr = ywOrderCntrMapper.selectOne(new QueryWrapper<YwOrderCntr>().eq("disable",vo.getOrderNo()).eq("cntr_no",detail.getCntrNo()));
        if(ywOrderCntr == null){
            return ResultUtil.build(400, "箱清单信息不存在");
        }
        if (ywOrderCntr.getTallyState() != 0) {
            return ResultUtil.build(400, "箱子已理货,请勿重新操作");
        }

        //修改计划清单表理货状态
        TrainPlan plan = trainPlanMapper.getByTrainPlanNo(vo.getTrainPlanNo());
        detail.setTallyFlag(1);
        detail.setTallyUserName(vo.getUserName());
        detail.setTallyMemberId(vo.getMid());
        detail.setTallyUserId(vo.getUserId());
        detail.setZxTime(LocalDateTime.now());
        detail.setPlanId(plan.getId());//直卸绑定班列号
        detail.setIsZzt(1);

        DeclareCar declareCar = declareCarMapper.selectById(vo.getDeclareId());
        YwOrder ywOrder = ywOrderMapper.selectOne(new QueryWrapper<YwOrder>().eq("disable",0).eq("order_no",vo.getOrderNo()));
        detail.setCarNo(declareCar.getCarNo());//选择的卡口车牌号
        detail.setTrainNumber(declareCar.getCarNo());//选择的卡口车牌号
        int index = detailMapper.updateById(detail);
        //修改卡口表declare_car

        declareCar.setTallyFlag(10);//理货状态
        //业务号
        if(StringUtils.isEmpty(declareCar.getOrderNo())){
            declareCar.setOrderNo(vo.getOrderNo());
            declareCar.setTxOrderNo(vo.getOrderNo());
            if(ywOrder != null){
                declareCar.setYwcode(ywOrder.getOrderType());
            }
        }else{
            declareCar.setTxOrderNo(vo.getOrderNo());
        }
        declareCar.setCntrA(detail.getCntrNo());
        declareCar.setTallyFlagB(10);
        declareCar.setHwnameA(detail.getGoods());
        declareCar.setEfFlagA(detail.getEfFlag());
        declareCar.setCntrSizeA(detail.getCntrSize());
        declareCarMapper.updateById(declareCar);

        //修改清单箱理货状态
        //业务中存在两次理货的数据,理货状态设置为第一次理货
        List<String> codes = Collections.singletonList(YwOrderTypeEnum.TZHK.getCode());
        if (codes.contains(declareCar.getYwcode())) {
            ywOrderCntr.setTallyState(5);
            ywOrderCntr.setEfFlag("F");
        } else {
            ywOrderCntr.setTallyState(10);
        }
        //业务中存在两次理货的数据,第二次设置结束理货时间
        ywOrderCntr.setTallyTime(LocalDateTime.now());
        ywOrderCntr.setTallyMemberId(vo.getMid());
        ywOrderCntr.setTallyUserId(vo.getUserId());
        ywOrderCntr.setTallyUserName(vo.getUserName());
        ywOrderCntrMapper.updateById(ywOrderCntr);

        //清空cntrinfo贝位
        CntrInfo info = infoMapper.getCntrInfoById(vo.getCntrNo());
        info.setBay("");
        info.setArea("");
        info.setCarNo(declareCar.getCarNo());
        info.setCntrWorkRemarkB(DdEnum.YTC.getName());
        info.setRemark("卸车理货(直提)");
        info.setConsignee(detail.getConsignee());
        info.setPayer(detail.getConsignee());
        info.setMachineName(vo.getMachineName());
        infoMapper.updateById(info);
        //生成箱动态
        CntrLog log = new CntrLog();
        BeanUtils.copyProperties(info,log);
        log.setCreatetime(LocalDateTime.now());
        cntrLogMapper.insert(log);

        //车辆预约表理货状态
//        LambdaQueryWrapper<VehicleReservation> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(VehicleReservation::getOrderNo,vo.getOrderNo())
//                .eq(VehicleReservation::getCntrNo,vo.getCntrNo())
//                .eq(VehicleReservation::getDisable,0);
//        VehicleReservation one = reservationMapper.selectOne(wrapper);
//        one.setTallyFlag(10);
//        int num = reservationMapper.updateById(one);
        if (index>0){
            return ResultUtil.ok();
        }

        return ResultUtil.fail();
    }

    @Override
    public List<CntrInfoVo> getZzCntrInfoAll(CntrInfoVo vo) {
        //自己计划下已经选择的箱子
        LambdaQueryWrapper<TrainPlanDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TrainPlanDetail::getPlanId,vo.getPlanId())
                .eq(TrainPlanDetail::getDisable,0);
        List<TrainPlanDetail> cntrs = detailMapper.selectList(wrapper);

        if (cntrs!=null && cntrs.size()>0){
            vo.setCntrNos(cntrs.stream().map(TrainPlanDetail::getCntrNo).collect(Collectors.toList()));
        }

        return baseMapper.getZzCntrInfoAll(vo);
    }

    @Override
    public void exportFile(HttpServletRequest request, HttpServletResponse response, String exportExcelPath, String exportExcelPath1,Integer flag) {
        Map<String, Object> map = new HashMap<>();
        if(flag==1){
            TemplateExportParams params = new TemplateExportParams(exportExcelPath);
            Workbook workbook = ExcelExportUtil.exportExcel(params, map);
            FileExcelUtil.downloadExcelIo(workbook, request, response, "发运模板");
        }else{
            TemplateExportParams params = new TemplateExportParams(exportExcelPath1);
            Workbook workbook = ExcelExportUtil.exportExcel(params, map);
            FileExcelUtil.downloadExcelIo(workbook, request, response, "到达模板");
        }
    }

    @Override
    public void exportChePiFile(HttpServletRequest request, HttpServletResponse response, String exportExcelPath) {
        Map<String, Object> map = new HashMap<>();

            TemplateExportParams params = new TemplateExportParams(exportExcelPath);
            Workbook workbook = ExcelExportUtil.exportExcel(params, map);
            FileExcelUtil.downloadExcelIo(workbook, request, response, "车皮导入模板");

    }

    @Override
    public ResultUtil<List<CntrInfoVo>> cntrUpload(Integer flag,UserDto user, MultipartFile file) {
        List<CntrInfoVo> list = new ArrayList<CntrInfoVo>();
        List<String> cntrList = new ArrayList<String>();
        ResultUtil<List<CntrInfoVo>> build = new ResultUtil<>();
        if (file != null) {
            try {
                List<CntrInfoVo> planCntrVos = EasypoiExcelUtils.importExcel(file, 0, 1, CntrInfoVo.class);
                QueryWrapper<CntrInfo> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("disable",0);
                List<CntrInfo> cntrInfos = baseMapper.selectList(queryWrapper);
                List<CntrSize> cntrSizes = cntrSizeMapper.selectList(new QueryWrapper<CntrSize>().eq("disable", 0));
                List<String> collect =new ArrayList<>();
                if(cntrSizes.size()>0){
                    collect = cntrSizes.stream().map(CntrSize::getCntrName).collect(Collectors.toList());
                }
                for (CntrInfoVo c:planCntrVos) { //校验数据
                    if (ObjectUtil.isEmpty(c)|| StrUtil.isBlank(c.getCntrNo())){
                        c.setErrorInfo("文件中有空数据;");
                        list.add(c);
                        break;
                    }
                    String errorInfo = checkCntr(cntrList, cntrInfos, c.getCntrNo());
                    if(c.getCntrSize().indexOf("-")!=-1){
                        c.setCntrSize(c.getCntrSize().split("-")[0]);
                    }
                    if(collect.size()>0){
                        if(!collect.contains(c.getCntrSize())){
                            errorInfo += "箱型不存在;";
                        }
                    }
                    if (!StrUtil.isNotBlank(c.getCntrNo())) {
                        errorInfo += "箱号未填;";
                    }
                    if (!StrUtil.isNotBlank(c.getEfFlag())) {
                        errorInfo += "空重未填;";
                    }
                    if (!StrUtil.isNotBlank(c.getBay())) {
                        errorInfo += "箱位未填;";
                    }
                    if (StrUtil.isNotBlank(c.getStartPort())) {
                        if(!(c.getStartPort().substring(c.getStartPort().length() - 1).equals("站"))){
                            c.setStartPort(c.getStartPort()+"站");
                        }
                    }
                    if (StrUtil.isNotBlank(c.getEndPort())) {
                        if(!(c.getEndPort().substring(c.getEndPort().length() - 1).equals("站"))){
                            c.setEndPort(c.getEndPort()+"站");
                        }
                    }
                    c.setErrorInfo(errorInfo);
                    if(StrUtil.isNotBlank(c.getInTimeStr())){
                        String[] split = c.getInTimeStr().split("\\.");

                        if(split.length<3){
                            String time= LocalDate.now().getYear()+"-"+ (Integer.valueOf(split[0]) < 10 ? "0"+split[0] : split[0])+"-"+(Integer.valueOf(split[1]) < 10 ? "0"+split[1] : split[1]);
                            c.setInTime(LocalDateTime.parse(time+" 00:00:00" , DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                        }else{
                            String time= split[0]+"-"+ (Integer.valueOf(split[1]) < 10 ? "0"+split[1] : split[1])+"-"+(Integer.valueOf(split[2]) < 10 ? "0"+split[2] : split[2]);
                            c.setInTime(LocalDateTime.parse(time+" 00:00:00" , DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                        }
                    }
                    c.setCreatetime(LocalDateTime.now());
                    c.setUserId(user.getId());
                    c.setUserName(user.getRealname());
                    if(flag==1){
                        //发运
                        c.setCntrWorkRemark(FyEnum.DFY.getName());
//                        if(StrUtil.isNotBlank(c.getGoods())){
//                            c.setEfFlag("F");
//                        }else{
//                            c.setEfFlag("E");
//                        }
                        c.setReceiveName(c.getConsigneeLx());
                        if(StringUtils.isEmpty(c.getOutTime())){
                            list.add(c);
                        }
                    }else{
                        //到达
                        if(c.getCntrSize().indexOf("二空")!=-1){
                            c.setCntrSize("20GP");
//                            c.setEfFlag("E");
                        }else if(c.getCntrSize().indexOf("二重")!=-1){
                            c.setCntrSize("20GP");
//                            c.setEfFlag("F");
                        }else if(c.getCntrSize().indexOf("四空")!=-1){
                            c.setCntrSize("40HC");
//                            c.setEfFlag("E");
                        }else if(c.getCntrSize().indexOf("四重")!=-1){
                            c.setCntrSize("40HC");
//                            c.setEfFlag("F");
                        }
                        c.setCntrWorkRemarkB(DdEnum.YLC.getName());
                        c.setReceiveName(c.getConsigneeLx());
                        if(StringUtils.isEmpty(c.getOutTime())){
                            list.add(c);
                        }
                        if(StrUtil.isNotBlank(c.getConsignee())){
                            c.setPayer(c.getConsignee());
                        }
                    }
                    if(StringUtils.isNotEmpty(c.getBay())){
                        if(c.getBay().matches(".*[\u4e00-\u9fa5]+.*")){
                            c.setArea(c.getBay());
                        }else{
                            c.setArea(c.getBay().split("-")[0]);
                        }
                    }
                }
                build = ResultUtil.build(list, ResultUtilCodeEnum.SUCCESS);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return build;
    }

    @Override
    public ResultUtil<List<CntrInfoVo>> chepiUpload( UserDto user, MultipartFile file) {
        List<CntrInfoVo> list = new ArrayList<CntrInfoVo>();
        List<String> cntrList = new ArrayList<String>();
        ResultUtil<List<CntrInfoVo>> build = new ResultUtil<>();
        if (file != null) {
            try {
                List<CntrInfoVo> planCntrVos = EasypoiExcelUtils.importExcel(file, 0, 1, CntrInfoVo.class);
                QueryWrapper<CntrInfo> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("disable",0);
                List<CntrInfo> cntrInfos = baseMapper.selectList(queryWrapper);
                for (CntrInfoVo c:planCntrVos) { //校验数据
                    if (ObjectUtil.isEmpty(c)|| StrUtil.isBlank(c.getCntrNo())){
                        c.setErrorInfo("文件中有空数据;");
                       continue;
                    }
                    String errorInfo = checkChepiCntr(cntrList, cntrInfos, c.getCntrNo());
                    if (!StrUtil.isNotBlank(c.getCntrNo())) {
                        errorInfo += "箱号未填;";
                    }
                    c.setErrorInfo(errorInfo);
                    list.add(c);
                }
                build = ResultUtil.build(list, ResultUtilCodeEnum.SUCCESS);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return build;
    }


    @Override
    public ResultUtil<T> importCntrList(HttpServletRequest request, List<CntrInfo> cntrList) {
        long start = System.currentTimeMillis();
//        for (CntrInfo cntrInfo : cntrList) {
//            cntrInfo.setEfFlag("F");
//        }
        for (CntrInfo cntrInfo : cntrList) {
            if(cntrInfo.getBay().matches(".*[\u4e00-\u9fa5]+.*")){
                cntrInfo.setArea(cntrInfo.getBay());
            }else{
                cntrInfo.setArea(cntrInfo.getBay().split("-")[0]);
            }
            cntrInfo.setStatus(0);
            cntrInfo.setInTime(LocalDateTime.now());
        }
        boolean b = saveOrUpdateBatch(cntrList);
        long end = System.currentTimeMillis();
        System.out.println("导入用时"+(end-start)+"ms");
        return b ? ResultUtil.ok() : ResultUtil.fail();
    }
    @Override
    public ResultUtil<T> updateConsigneeMsg(CntrInfoVo vo) {
        List<String> list = vo.getCntrNoList();
        List<CntrInfo> cntrInfoList = new ArrayList<>();
        for (String cntrNo : list) {
            CntrInfo info = getById(cntrNo);
            info.setConsignee(vo.getConsignee());//收货人
            info.setConsigneeLx(vo.getConsigneeLx());//收货联系人
            info.setConsigneePhone(vo.getConsigneePhone());//收货联系人方式
            info.setEndPort(vo.getEndPort());//到站信息
            cntrInfoList.add(info);
        }
        boolean b = updateBatchById(cntrInfoList);
        if (b){
            return ResultUtil.ok();
        }
        return ResultUtil.fail();
    }

    @Override
    public ResultUtil<T> importSgjCntrList(HttpServletRequest request,List<CntrInfo> list) {
       List<String> cntrnos =  list.stream().map(CntrInfo::getCntrNo).collect(Collectors.toList());
       List<CntrInfo> cntrInfoList = baseMapper.selectList(new LambdaQueryWrapper<CntrInfo>().in(CntrInfo::getCntrNo,cntrnos));
        // 创建一个 Map 来将箱号映射到 TrainNumber
        Map<String, String> trainNumberMap = list.stream()
                .collect(Collectors.toMap(CntrInfo::getCntrNo, CntrInfo::getTrainNumber));
        // 遍历从数据库中获取的 CntrInfo 列表，更新 TrainNumber
        for (CntrInfo cntrInfo : cntrInfoList) {
            if (cntrnos.contains(cntrInfo.getCntrNo())) {
                // 获取对应箱号的 TrainNumber
                String trainNumber = trainNumberMap.get(cntrInfo.getCntrNo());
                if (trainNumber != null) {
                    cntrInfo.setTrainNumber(trainNumber);
                }
            }
        }
        boolean b= updateBatchById(cntrInfoList);
       return b ? ResultUtil.ok() : ResultUtil.fail();
    }

    private String checkCntr(List<String> cntrList, List<CntrInfo> cntrInfoVos, String cntrNo) {
//        boolean checkDigit = CheckUtils.checkDigit(cntrNo);
//        if (!checkDigit) {
//            return "箱号格式不正确;";
//        }
        //箱号校验暂时仅校验位数
        if (cntrNo == null || cntrNo.trim().length() != 11) {
            return "箱号格式不正确;";
        }
        if (cntrList.contains(cntrNo)) {
            return "箱号重复;";
        }
        boolean isCntrNo = cntrInfoVos.stream().filter(s -> StringUtils.isNotEmpty(s.getCntrWorkRemark()) || StringUtils.isNotEmpty(s.getCntrWorkRemarkB())).anyMatch(item -> cntrNo.equals(item.getCntrNo()));
        if(isCntrNo){
            return "该箱号已存在;";
        }
        cntrList.add(cntrNo);
        return "";
    }
    private String checkChepiCntr(List<String> cntrList, List<CntrInfo> cntrInfoVos, String cntrNo) {
        //箱号校验暂时仅校验位数
        if (cntrNo == null || cntrNo.trim().length() != 11) {
            return "箱号格式不正确;";
        }
        cntrList.add(cntrNo);
        return "";
    }
}
